#define CSCHED_MSECS_PER_TICK 10
#define CSCHED_MSECS_PER_TSLICE \
(CSCHED_MSECS_PER_TICK * CSCHED_TICKS_PER_TSLICE)
-#define CSCHED_CREDITS_PER_TICK 100
+#define CSCHED_CREDITS_PER_MSEC 100000
#define CSCHED_CREDITS_PER_TSLICE \
- (CSCHED_CREDITS_PER_TICK * CSCHED_TICKS_PER_TSLICE)
+ (CSCHED_MSECS_PER_TSLICE * CSCHED_CREDITS_PER_MSEC)
#define CSCHED_CREDITS_PER_ACCT \
- (CSCHED_CREDITS_PER_TICK * CSCHED_TICKS_PER_ACCT)
+ (CSCHED_CREDITS_PER_MSEC * CSCHED_MSECS_PER_TSLICE)
+#define CSCHED_STIME_TO_CREDIT(_t) ((_t)*CSCHED_CREDITS_PER_MSEC/MILLISECS(1))
/*
struct csched_dom *sdom;
struct vcpu *vcpu;
atomic_t credit;
+ s_time_t start_time; /* When we were scheduled (used for credit) */
uint16_t flags;
int16_t pri;
#ifdef CSCHED_STATS
list_del_init(&svc->runq_elem);
}
+void burn_credits(struct csched_vcpu *svc, s_time_t now)
+{
+ s_time_t delta;
+
+ /* Assert svc is current */
+ ASSERT(svc==CSCHED_VCPU(per_cpu(schedule_data, svc->vcpu->processor).curr));
+
+ if ( is_idle_vcpu(svc->vcpu) )
+ return;
+
+ delta = (now - svc->start_time);
+
+ if ( delta > 0 ) {
+ atomic_sub(CSCHED_STIME_TO_CREDIT(delta)+1, &svc->credit);
+ svc->start_time = now;
+ }
+}
+
static inline void
__runq_tickle(unsigned int cpu, struct csched_vcpu *new)
{
/*
* Update credits
*/
- atomic_sub(CSCHED_CREDITS_PER_TICK, &svc->credit);
+ burn_credits(svc, NOW());
/*
* Put this VCPU and domain back on the active list if it was
CSCHED_STAT_CRANK(schedule);
CSCHED_VCPU_CHECK(current);
+ /* Update credits */
+ burn_credits(scurr, now);
+
/*
* Select next runnable local VCPU (ie top of local runq)
*/
cpu_clear(cpu, csched_priv.idlers);
}
+ if ( !is_idle_vcpu(snext->vcpu) )
+ snext->start_time = now;
+
/*
* Return task to run next...
*/
"\trunq_sort = %u\n"
"\tdefault-weight = %d\n"
"\tmsecs per tick = %dms\n"
- "\tcredits per tick = %d\n"
+ "\tcredits per msec = %d\n"
"\tticks per tslice = %d\n"
"\tticks per acct = %d\n"
"\tmigration delay = %uus\n",
csched_priv.runq_sort,
CSCHED_DEFAULT_WEIGHT,
CSCHED_MSECS_PER_TICK,
- CSCHED_CREDITS_PER_TICK,
+ CSCHED_CREDITS_PER_MSEC,
CSCHED_TICKS_PER_TSLICE,
CSCHED_TICKS_PER_ACCT,
vcpu_migration_delay);